var Utils = function() {
	return {
		isArray: function(obj) {
			return (obj && obj.constructor == Array);
		}
	}
}();

function Template(htmlTemplate) {
	this.tpl = htmlTemplate;
	// Bracket regular expression.
	this.bracketExp = /\[(\S+)]/g;
	// Braces regular expression.
	this.bracesExp = /\${\S+}/g;
}
Template.prototype.compileObject = function(obj, htmlTemplate) {
	var html;
	if (htmlTemplate) {
		html = htmlTemplate;
	} else {
		html = this.tpl
	}
	var matches = html.match(this.bracesExp);
	for (var i = 0, len = matches.length; i < len; i++) {
		var value = matches[i].substring(2, matches[i].length - 1);
		var regEx = null;
		if (value.indexOf('[') > -1) {
			regEx = new RegExp("\\${" + value.replace(this.bracketExp, '\\[$1\\]') + "}", "g");
			value = eval("obj." + value);
		} else if (value.indexOf('.') > -1) {
			regEx = new RegExp("\\${" + value + "}", "g");
			value = eval("obj." + value);
		} else {
			regEx = new RegExp("\\${" + value + "}", "g");
			value = obj[value];
		}
		html = html.replace(regEx, value);
	}
	return html;
}
Template.prototype.compile = function(obj) {
	var html = this.tpl;
	if (Utils.isArray(obj)) {
		for (var i = 0, len = obj.length; i < len; i++) {
			html = this.compileObject(obj[i], html);
		}
	} else {
		html = this.compileObject(obj);
	}
	return html;
}

function buildTemplate(tplId, json) {
	var bracketExp = /\[(\S+)]/g;
	var tpl = $('#' + tplId).html();
	
	var matches = tpl.match(/\${\S+}/g);
	$.each(matches, function(id, val) {
		var value = val.substring(2, val.length - 1);
		var regEx = null;
		if (value.indexOf('[') > -1) {	
			regEx = new RegExp("\\${" + value.replace(bracketExp, '\\[$1\\]') + "}", "g");
			value = eval("json." + value);
		} else if (value.indexOf('.') > -1) {
			regEx = new RegExp("\\${" + value + "}", "g");
			value = eval("json." + value);
		} else {
			regEx = new RegExp("\\${" + value + "}", "g");
			value = json[value];
		}
		tpl = tpl.replace(regEx, value);
	});
	return tpl;
}
